Overview
Integrate Civic with Anthropic’s Messages API using the native MCP connector feature. This is built directly into the API - no separate MCP client needed!
Native MCP Support : The Anthropic Messages API includes built-in MCP connector support. Just add the mcp_servers parameter to your API calls.
Prerequisites
Prerequisites:
Node.js 18+ project (Next.js 14+ or any Node.js framework)
Civic account - Create account
Connect services at nexus.civic.com (GitHub, Slack, etc.)
Anthropic API Key - Get yours at console.anthropic.com
Complete Civic Auth setup (see Access Token Setup below)
Access Token Setup (Next.js + Civic Auth)
Why Civic Auth? Civic needs to identify which user is accessing tools and authorize their permissions. Civic Auth provides the secure access token. (Support for additional identity providers coming soon.)
1. next.config.ts
2. API Route
3. Middleware
4. Get Token
import { createCivicAuthPlugin } from "@civic/auth/nextjs"
import type { NextConfig } from "next" ;
const nextConfig : NextConfig = {};
const withCivicAuth = createCivicAuthPlugin ({ clientId: "YOUR_CLIENT_ID" });
export default withCivicAuth ( nextConfig )
File: src/app/api/auth/[...civicauth]/route.tsimport { handler } from "@civic/auth/nextjs"
export const GET = handler ()
export const POST = handler ()
File: src/middleware.tsimport { authMiddleware } from "@civic/auth/nextjs/middleware"
export default authMiddleware () ;
export const config = { matcher: [ '/((?!_next|favicon.ico|.* \\ .png).*)' ,] };
import { getTokens } from "@civic/auth/nextjs" ;
const { accessToken } = await getTokens ();
// Use in headers:
headers : { Authorization : `Bearer ${ accessToken } ` }
Full Integration Guide Complete Next.js setup with frontend components, configuration options, and deployment details
AI Prompt for Next.js Use Claude, ChatGPT, or other AI assistants to automatically set up Civic Auth
Non-Next.js: Forward a Bearer token from your frontend or validate incoming tokens server-side (see /libraries/auth-verify ).
Environment Variables
Create a .env.local file in your project root:
# Get your Client ID at https://auth.civic.com
CIVIC_AUTH_CLIENT_ID = your_client_id_here
# Anthropic API key
ANTHROPIC_API_KEY = your_anthropic_api_key
Getting your Civic Client ID:
Visit auth.civic.com
Create a new application or use an existing one
Copy the Client ID from your application settings
Installation
Install the required packages:
npm install @anthropic-ai/sdk
Note: No MCP SDK required! The MCP connector is built into the Anthropic SDK.
Basic Setup
Create Message with MCP Connector
import Anthropic from '@anthropic-ai/sdk' ;
import { getTokens } from '@civic/auth/nextjs' ;
async function createMessage ( userMessage : string ) {
const { accessToken } = await getTokens ();
if ( ! accessToken ) {
throw new Error ( 'No access token available. User must be authenticated.' );
}
const client = new Anthropic ({
apiKey: process . env . ANTHROPIC_API_KEY ! ,
});
const response = await client . messages . create ({
model: 'claude-sonnet-4-5' ,
max_tokens: 1024 ,
messages: [{ role: 'user' , content: userMessage }],
mcp_servers: [
{
type: 'url' ,
url: 'https://nexus.civic.com/hub/mcp' ,
name: 'civic' ,
authorization_token: accessToken ,
},
],
}, {
headers: {
'anthropic-beta' : 'mcp-client-2025-04-04' ,
},
});
return response ;
}
Key Points:
Add mcp_servers parameter to your messages.create() call
Include the beta header: "anthropic-beta": "mcp-client-2025-04-04"
Pass your Civic access token as authorization_token
That’s it! No tool looping, no MCP client setup
Complete Example: Next.js API Route
// app/api/chat/route.ts
import { NextRequest , NextResponse } from 'next/server' ;
import Anthropic from '@anthropic-ai/sdk' ;
import { getTokens } from '@civic/auth/nextjs' ;
export async function POST ( req : NextRequest ) {
try {
const { messages } = await req . json ();
if ( ! messages || ! Array . isArray ( messages )) {
return NextResponse . json (
{ error: 'Invalid request: messages array required' },
{ status: 400 }
);
}
const { accessToken } = await getTokens ();
if ( ! accessToken ) {
return NextResponse . json (
{ error: 'Not authenticated' },
{ status: 401 }
);
}
const client = new Anthropic ({
apiKey: process . env . ANTHROPIC_API_KEY ! ,
});
const response = await client . messages . create ({
model: 'claude-sonnet-4-5' ,
max_tokens: 4096 ,
messages ,
mcp_servers: [
{
type: 'url' ,
url: 'https://nexus.civic.com/hub/mcp' ,
name: 'civic' ,
authorization_token: accessToken ,
},
],
}, {
headers: {
'anthropic-beta' : 'mcp-client-2025-04-04' ,
},
});
return NextResponse . json ( response );
} catch ( error ) {
console . error ( 'Anthropic API error:' , error );
const errorMessage = error instanceof Error ? error . message : 'Failed to process request' ;
const statusCode = errorMessage . includes ( 'authentication' ) ? 401 : 500 ;
return NextResponse . json (
{ error: errorMessage },
{ status: statusCode }
);
}
}
Streaming Responses
For real-time streaming:
const stream = await client . messages . create ({
model: 'claude-sonnet-4-5' ,
max_tokens: 4096 ,
messages: [{ role: 'user' , content: 'List my GitHub repositories' }],
mcp_servers: [
{
type: 'url' ,
url: 'https://nexus.civic.com/hub/mcp' ,
name: 'civic' ,
authorization_token: accessToken ,
},
],
stream: true ,
}, {
headers: {
'anthropic-beta' : 'mcp-client-2025-04-04' ,
},
});
for await ( const event of stream ) {
if ( event . type === 'content_block_delta' && event . delta . type === 'text_delta' ) {
console . log ( event . delta . text );
}
}
Restrict which tools Claude can use:
mcp_servers : [
{
type: 'url' ,
url: 'https://nexus.civic.com/hub/mcp' ,
name: 'civic' ,
authorization_token: accessToken ,
tool_configuration: {
enabled: true ,
allowed_tools: [ 'github__list_repos' , 'slack__search_messages' ]
}
},
]
Key Advantages
Native Integration Built directly into Messages API - no extra SDKs
Automatic Tools Claude discovers and calls tools automatically
Simple Setup Just add mcp_servers parameter to API calls
Streaming Support Real-time responses with stream: true
Civic Authentication
Required MCP Server Config
mcp_servers : [
{
type: 'url' ,
url: 'https://nexus.civic.com/hub/mcp' ,
name: 'civic' ,
authorization_token: accessToken , // Civic access token
},
]
import { getTokens } from "@civic/auth/nextjs" ;
const { accessToken } = await getTokens ();
Claude returns mcp_tool_use blocks in the response:
{
"type" : "mcp_tool_use" ,
"id" : "mcptoolu_01234..." ,
"name" : "github__list_repos" ,
"input" : {
"owner" : "username"
}
}
These are handled automatically by Claude - you don’t need to process them manually.
Current Limitations
The MCP connector currently only supports:
Tool calls (not MCP resources or prompts)
HTTP servers (not STDIO servers)
SSE and Streamable HTTP transports
Amazon Bedrock and Google Vertex integrations are not yet supported.
Comparison with Other Approaches
Feature Anthropic MCP Connector OpenAI Agents SDK Vercel AI SDK Setup Complexity Low Low Medium MCP SDK Needed No No Yes Tool Looping No (automatic) No (automatic) Yes (manual) Best For Direct API usage Quick prototypes Next.js apps Streaming Yes Yes Yes
Next Steps
Test with Simple Queries
Try “list my GitHub repos” or “search Slack messages about X”
Configure Tool Access
Use tool_configuration to restrict which tools Claude can use
Deploy
Deploy your application to production
Anthropic MCP Docs Learn more about Anthropic’s MCP connector
Need Help? Join our developer community for technical support